package com.rede.didiok.user.service.impl;

import java.util.*;

import javax.annotation.Resource;

import cn.hutool.core.bean.BeanUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rede.didiok.common.constant.conf.MessageConf;
import com.rede.didiok.common.constant.conf.SQLConf;
import com.rede.didiok.common.constant.conf.SysConf;
import com.rede.didiok.common.constant.global.Constants;
import com.rede.didiok.common.domainEvent.EventAction;
import com.rede.didiok.common.dto.admin.AdminDto;
import com.rede.didiok.common.dto.user.GeneralEditDto;
import com.rede.didiok.common.enums.AuditStatusEnum;
import com.rede.didiok.common.enums.ResourceTypeEnum;
import com.rede.didiok.common.enums.StatusEnum;
import com.rede.didiok.common.exception.exceptionType.FeignException;
import com.rede.didiok.common.feign.AdminFeignClient;
import com.rede.didiok.common.feign.RankFeignClient;
import com.rede.didiok.common.holder.RequestHolder;
import com.rede.didiok.common.utils.R;
import com.rede.didiok.common.utils.ResultUtil;
import com.rede.didiok.common.utils.StringUtils;
import com.rede.didiok.common.utils.business.DomainEventUtil;
import com.rede.didiok.user.dao.GeneralEditDao;
import com.rede.didiok.user.entity.GeneralEditEntity;
import com.rede.didiok.user.entity.UserEntity;
import com.rede.didiok.user.service.GeneralEditService;
import com.rede.didiok.user.service.UserService;


@Service("generalEditService")
public class GeneralEditServiceImpl extends ServiceImpl<GeneralEditDao, GeneralEditEntity> implements GeneralEditService {

    @Resource
    GeneralEditDao generalEditDao;
    @Resource
    UserService userService;
    @Resource
    RankFeignClient rankFeignClient;
    @Resource
    AdminFeignClient adminFeignClient;
    @Resource
    private DomainEventUtil domainEventUtil;

    /***************************** didiok-admin:start **************************/
    // region  didiok-admin

    @Override
    public IPage<GeneralEditEntity> getGeneralEditList(GeneralEditDto generalEditDto) {
        QueryWrapper<GeneralEditEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(generalEditDto.getKeyword()) && !StringUtils.isEmpty(generalEditDto.getKeyword())) {
            queryWrapper.like(SQLConf.CONTENT, generalEditDto.getKeyword().trim());
        }
        if (generalEditDto.getAuditStatus() != null) {
            queryWrapper.eq(SQLConf.AUDIT_STATUS, generalEditDto.getAuditStatus());
        }

        Page<GeneralEditEntity> page = new Page<>();
        page.setCurrent(generalEditDto.getCurrentPage());
        page.setSize(generalEditDto.getPageSize());
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        if (StringUtils.isNotEmpty(generalEditDto.getOrderByAscColumn())) {
            // 将驼峰转换成下划线
            String column = StringUtils.underLine(new StringBuffer(generalEditDto.getOrderByAscColumn())).toString();
            queryWrapper.orderByAsc(column);
        } else if (StringUtils.isNotEmpty(generalEditDto.getOrderByDescColumn())) {
            // 将驼峰转换成下划线
            String column = StringUtils.underLine(new StringBuffer(generalEditDto.getOrderByDescColumn())).toString();
            queryWrapper.orderByDesc(column);
        } else {
            queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        }
        IPage<GeneralEditEntity> pageList = this.page(page, queryWrapper);

        // 设置用户信息
        List<String> userUidList = new ArrayList<>();
        List<GeneralEditEntity> generalEdits = pageList.getRecords();
        generalEdits.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                userUidList.add(item.getCreateUserUid());
            }
        });
        Map<String, UserEntity> userMap = new HashMap<>();
        if (userUidList.size() > 0) {
            Collection<UserEntity> userCollection = userService.listByIds(userUidList);
            List<UserEntity> userList = userService.convertUserList(userCollection);
            userService.setUserAvatar(userList);
            userList.forEach(item -> {
                userMap.put(item.getUid(), item);
            });
        }

        generalEdits.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                item.setUser(userMap.get(item.getCreateUserUid()));
            }
        });
        pageList.setRecords(generalEdits);
        return pageList;
    }

    @Override
    public String deleteBatchGeneralEdit(List<GeneralEditDto> generalEditVOList) {
        if (generalEditVOList.size() <= 0) {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }
        List<String> uids = new ArrayList<>();
        generalEditVOList.forEach(item -> {
            uids.add(item.getUid());
        });

        Collection<GeneralEditEntity> generalEditCollection = this.listByIds(uids);
        generalEditCollection.forEach(item -> {
            item.setUpdateTime(new Date());
            item.setStatus(StatusEnum.DISABLED);
            // 发送删除勘误事件
            GeneralEditDto dto = new GeneralEditDto();
            BeanUtils.copyProperties(item, dto);
            domainEventUtil.publishEvent(EventAction.GENERAL_EDIT_DELETE, dto);
        });
        Boolean save = this.updateBatchById(generalEditCollection);
        if (save) {
            return ResultUtil.successWithMessage(MessageConf.DELETE_SUCCESS);
        } else {
            return ResultUtil.errorWithMessage(MessageConf.DELETE_FAIL);
        }
    }


    /**
     * 审批修改
     *
     * @param generalEditDto
     * @return
     */
    @Override
    public String auditGeneralEdit(GeneralEditDto generalEditDto) {
        boolean flg = false;
        GeneralEditEntity generalEdit = getById(generalEditDto.getUid());
        //判断审批的资源类型
        if (ResourceTypeEnum.RANK_MEMBER.getType().equals(generalEditDto.getBizType())) {
            //判断是博客
            R updateResult = rankFeignClient.updateRankMemberContent(generalEditDto);
            if (updateResult.getCode() == 0) {
                flg = updateResult.getData(new TypeReference<Boolean>(){});
            }else {
                throw new FeignException("feign调用异常(修改rankMember的content失败)");
            }
        }  else {
            return ResultUtil.errorWithMessage("审核的资源不存在");
        }

        if (flg) {
            R adminResult = adminFeignClient.getAdminByUid(RequestHolder.getAdminUid());
            AdminDto admin = null;
            if (adminResult.getCode() == 0) {
                admin = adminResult.getData(new TypeReference<AdminDto>(){});
            }else {
                throw new FeignException("feign调用异常（通过 id 获取管理员）：失败");
            }

            generalEdit.setAuditStatus(generalEditDto.getAuditStatus());
            generalEdit.setRejectReason(generalEditDto.getRejectReason());
            generalEdit.setAuditName(admin.getNickname());
            generalEdit.setAuditTime(new Date());
            boolean isSave = this.updateById(generalEdit);
            if (isSave) {
                // 发送删除勘误事件
                GeneralEditDto dto = new GeneralEditDto();
                BeanUtils.copyProperties(generalEdit, dto);
                domainEventUtil.publishEvent(EventAction.GENERAL_EDIT_AUDIT, dto);
            }
            return ResultUtil.successWithMessage(MessageConf.OPERATION_SUCCESS);
        } else {
            return ResultUtil.errorWithMessage(MessageConf.OPERATION_FAIL);
        }
    }

    // endregion
    /***************************** didiok-admin:end **************************/



    /***************************** didiok-web:start **************************/
    // region didiok-web

    /**
     * 通用修改
     *
     * @param generalEditDto
     * @return
     */
    @Override
    public String generalEdit(GeneralEditDto generalEditDto) {
        String userUid = RequestHolder.getUserUid();
        if (userUid == null) {
            return ResultUtil.errorWithMessage(Constants.USER_UID_EMPTY);
        }
        GeneralEditEntity generalEdit = new GeneralEditEntity();
        generalEditDto.setUserUid(userUid);
        generalEditDto.setAuditStatus(AuditStatusEnum.WAIT);
        BeanUtil.copyProperties(generalEditDto, generalEdit, SysConf.STATUS);
        Integer result = generalEditDao.generalEdit(generalEdit);
        if (result == 1) {
            // 发送新增勘误事件
            GeneralEditDto dto = new GeneralEditDto();
            BeanUtils.copyProperties(generalEdit, dto);
            domainEventUtil.publishEvent(EventAction.GENERAL_EDIT_ADD, dto);
            return ResultUtil.successWithMessage(MessageConf.OPERATION_SUCCESS);
        } else {
            return ResultUtil.errorWithMessage(MessageConf.OPERATION_FAIL);
        }
    }

    // endregion
    /***************************** didiok-web:end **************************/

}